package com.example.demo.game;

import com.example.demo.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

@Component
public class Matcher {
    private Queue<User> normalQueue = new LinkedList<>();
    private Queue<User> highQueue = new LinkedList<>();
    private Queue<User> veryHighQueue = new LinkedList<>();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private RoomManger roomManger;


    private ObjectMapper objectMapper = new ObjectMapper();
    //操作匹配队列的方法
    //把玩家放到匹配队列中
    public void add(User user){
        if (user.getScore() < 2000){
            synchronized(normalQueue){
                normalQueue.offer(user);
                normalQueue.notify();
            }
            System.out.println("玩家 " + user.getUsername() + " 加入到了normalQueue中");
        }else if (user.getScore() >= 2000 && user.getScore() < 3000){
            synchronized (highQueue){
                highQueue.offer(user);
                highQueue.notify();
            }

            System.out.println("玩家 " + user.getUsername() + " 加入到了highQueue中");
        }else {
            synchronized (veryHighQueue){
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }
            System.out.println("玩家 " + user.getUsername() + " 加入到了veryHighQueue中");

        }
    }

    public void remove(User user){
        if (user.getScore() < 2000){
            synchronized (normalQueue){
                normalQueue.remove(user);
            }
            System.out.println("玩家 " + user.getUsername() + " 停止匹配");
        }else if (user.getScore() >= 2000 && user.getScore() < 3000){
            synchronized (highQueue){
                highQueue.remove(user);
            }
            System.out.println("玩家 " + user.getUsername() + " 停止匹配");
        }else {
            synchronized (veryHighQueue){
                veryHighQueue.remove(user);
            }
            System.out.println("玩家 " + user.getUsername() + " 停止匹配");

        }
    }

    public Matcher(){
        //创建三个线程，分别针对这三个匹配队列，进行扫描
        Thread t1 = new Thread(){
            @Override
            public void run() {
                //扫描normalQueue
                while (true){
                    handlerMatch(normalQueue);
                }
            }
        };
        t1.start();

        Thread t2 = new Thread(){
            @Override
            public void run() {
                while (true){
                    handlerMatch(highQueue);
                }
            }
        };
        t2.start();

        Thread t3 = new Thread(){
            @Override
            public void run() {
                while (true){
                    handlerMatch(veryHighQueue);
                }
            }
        };
        t3.start();
    }

    private void handlerMatch(Queue<User> matchQueue){
        synchronized (matchQueue){
            try {
                //1 检测队列中元素个树是否达到2
                // 队列的初始情况可能为 空
                // 如果网队列中添加一个元素，这时也不能进行匹配
                // 所以用while 循环判定更合理
                while (matchQueue.size() < 2){
                    matchQueue.wait();
                }

                //2 尝试从队列中取出两个玩家
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                System.out.println("匹配两个玩家：" + player1.getUsername() + ", " + player2.getUsername());

                //3 获取到玩家的websocket的会话   为了告诉玩家匹配成功
                WebSocketSession session1 = onlineUserManager.getFromGameHall(player1.getUserid());
                WebSocketSession session2 = onlineUserManager.getFromGameHall(player2.getUserid());
                if (session1 == null){
                    // 如果玩家1不在线了，就把玩家2重新放入匹配队列中
                    matchQueue.offer(player2);
                    return;
                }
                if (session2 == null){
                    matchQueue.offer(player1);
                    return;
                }

                if (session1 == session2){
                    matchQueue.offer(player1);
                    return;
                }

                // 4 将两个玩家放到同一个游戏房间中
                Room room = new Room();
                roomManger.add(room,player1.getUserid(),player2.getUserid());

                //5 给玩家反馈信息：你匹配到了队手
                MatchResponse matchResponse1 = new MatchResponse();
                matchResponse1.setOk(true);
                matchResponse1.setMessage("matchSuccess");
                String json1 = objectMapper.writeValueAsString(matchResponse1);
                session1.sendMessage(new TextMessage(json1));

                MatchResponse matchResponse2 = new MatchResponse();
                matchResponse2.setOk(true);
                matchResponse2.setMessage("matchSuccess");
                String json2 = objectMapper.writeValueAsString(matchResponse2);
                session2.sendMessage(new TextMessage(json2));
            }catch (IOException | InterruptedException e){
                e.printStackTrace();
            }
        }

    }
}
